package com.village.friend.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.internal.util.file.IOUtils;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.village.friend.constant.ChatWords;
import com.village.friend.constant.PayStatus;
import com.village.friend.pay.Constants;
import com.village.friend.pay.wechat.WXConfig;
import com.village.friend.pay.wechat.WXPay;
import com.village.friend.pay.wechat.WXPayUtil;
import com.village.friend.service.OpenImService;
import com.village.friend.service.UserOrderService;
import com.village.friend.service.UserPolicyService;
import com.village.friend.service.UserService;
import com.village.friend.utils.OrderUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @author dingzhiwei jmdhappy@126.com
 * @version V1.0
 * @Description: 接收处理支付宝, 微信的通知
 * @date 2017-07-05
 * @Copyright: www.xxpay.org
 */
@RestController
@Slf4j
@RequestMapping("/notify")
@Api(tags = "支付回调管理器")
public class NotifyController {

    @Autowired
    private UserOrderService orderService;

    @Autowired
    private UserService userService;

    @Autowired
    private UserPolicyService policyService;

    @Autowired
    private WXConfig wxConfig;

    @Autowired
    OpenImService openImService;

    /**
     * 微信支付(统一下单接口)后台通知响应
     *
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    @RequestMapping("/wxPayNotifyRes")
    @ResponseBody
    @ApiOperation(value = "微信下单回调")
    public String wxPayNotifyRes(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String logPrefix = "【微信支付回调通知】";
        log.info("====== 开始接收微信支付回调通知 ======");
        try {
            String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlResult);
            //校验结果是否成功
            if (!Constants.RETURN_VALUE_SUCCESS.equalsIgnoreCase(result.getResultCode())
                    && !Constants.RETURN_VALUE_SUCCESS.equalsIgnoreCase(result.getReturnCode())) {
                log.error("returnCode={},resultCode={},errCode={},errCodeDes={}", result.getReturnCode(), result.getResultCode(), result.getErrCode(), result.getErrCodeDes());
                return WxPayNotifyResponse.fail("notify data failed");
            }
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(xmlResult);
            log.info("wxpayback={}", JSON.toJSONString(notifyMap));
            WXPay wxpay = new WXPay(wxConfig);
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
                // 签名正确
                String orderNo = result.getOutTradeNo();
                // 分转成元
                BigDecimal transAmount = BigDecimal.valueOf(result.getTotalFee()).divide(BigDecimal.valueOf(100));
                OrderUtils.payStatusChange(orderService, userService, policyService, openImService, orderNo, transAmount, PayStatus.SUCCESS);

            } else {
                // 签名错误，如果数据里没有sign字段，也认为是签名错误
                return WxPayNotifyResponse.fail("签名失败");
            }
            // 业务系统后端通知
            log.info("====== 完成接收微信支付回调通知 ======");
            return WxPayNotifyResponse.success("处理成功");
        } catch (WxPayException e) {
            //出现业务错误
            log.error("微信回调结果异常,异常原因", e);
            log.error("err_code:{},{},{}", logPrefix, e.getErrCode(), e.getErrCodeDes());
            return WxPayNotifyResponse.fail(e.getMessage());
        } catch (Exception e) {
            log.error("微信回调结果异常,异常原因", e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    /**
     * 支付宝回调
     */
    @ApiOperation(value = "支付宝下单回调")
    @RequestMapping(value = "/aliPayNotifyRes", method = RequestMethod.POST)
    public String aliPayNotifyRes(HttpServletRequest request) {
        Map<String, String> paramMap = new HashMap();
        //方式一：getParameterMap()，获得请求参数map
        Map<String, String[]> map = request.getParameterMap();
        //参数名称
        Set<String> key = map.keySet();
        //参数迭代器
        Iterator<String> iterator = key.iterator();
        while (iterator.hasNext()) {
            String k = iterator.next();
            paramMap.put(k, map.get(k)[0]);
        }
        System.out.println("paramMap=====" + paramMap.toString());
        if (paramMap.isEmpty()) {
            return Constants.RETURN_ALIPAY_VALUE_FAIL;
        }
        String trade_status = paramMap.get("trade_status");        // 交易状态
        String orderNo = paramMap.get("out_trade_no");
        BigDecimal transAmount = new BigDecimal(paramMap.get("buyer_pay_amount"));
        log.info("====== 支付宝下单回调 ======" + trade_status);
        log.info("====== 支付宝下单回调 ======" + orderNo);
        log.info("====== 支付宝下单回调 ======" + transAmount);
        // 支付状态成功或者完成
        if (trade_status.equals(Constants.AlipayConstant.TRADE_STATUS_SUCCESS) || trade_status.equals(Constants.AlipayConstant.TRADE_STATUS_FINISHED)) {
            OrderUtils.payStatusChange(orderService, userService, policyService, openImService,orderNo, transAmount, PayStatus.SUCCESS);
            return Constants.RETURN_ALIPAY_VALUE_SUCCESS;
        }
        return Constants.RETURN_ALIPAY_VALUE_FAIL;
    }


}
